package com.example.micrauth.filter;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.example.common.utils.JwtUtil;
import com.example.micrauth.domain.vo.LoginUserVO;
import io.jsonwebtoken.Claims;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @description: 认证过滤器，在请求前执行一次，获取请求头token信息，在通过token值从redis中查询用户信息。
 * @author: uu
 * @date: 2024/3/1 1:00
 * @version: 1.0
 */
@Component
@Slf4j
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    @Autowired
    private JwtUtil jwtUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String token = request.getHeader("Authorization");
        log.info("request get token = {}", token);
        if (StrUtil.isNotEmpty(token)) {
            Claims claims = null;
            try {
                claims = jwtUtil.parseToken(token);
            } catch (Exception e) {
                log.info("jwt filter token parseToken exception = {}", e.getMessage());
                filterChain.doFilter(request, response);
                return;
            }
            String uuid = (String) claims.get("token");
            // 从redis中获取数据
            LoginUserVO loginUserVO = (LoginUserVO) jwtUtil.getLoginUser(uuid);
            log.info("jwt filter loginUserVO = {}", loginUserVO);
            // 获取到loginUserVO
            if (ObjectUtil.isNotNull(loginUserVO)) {
                Instant lastTime = loginUserVO.getSysUser().getLastTime().toInstant();
                Instant nowTime = new Date().toInstant();
                // 大于二十分钟再刷新token
                if (Duration.between(nowTime, lastTime).toMinutes() > 20) {
                    // TODO 刷新token 刷新redis中的用户信息的时间
                    jwtUtil.refreshToken(loginUserVO, loginUserVO.getToken());
                }
                // 鉴权
                UsernamePasswordAuthenticationToken authenticationToken =
                        new UsernamePasswordAuthenticationToken(loginUserVO, null, loginUserVO.getAuthorities());
                // 将用户信息存储到SecurityContext中
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }
        }
        filterChain.doFilter(request, response);
    }
}
